package cn.funeralobjects.common.web.controller;

import cn.funeralobjects.common.enums.SimpleStatus;
import cn.funeralobjects.common.service.EnableService;
import cn.funeralobjects.util.ReactorUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import reactor.core.publisher.Mono;

/**
 * 带有启用禁用状态的controller
 *
 * @author FuneralObjects
 * Create date: 2020/4/28 10:00 AM
 */
public interface RestEnableController<VO, Entity, ID> extends SimpleStatusControllerBinder, ModelMapperController<Entity, VO>, IdController<ID> {

    /**
     * 启用禁用的业务接口
     *
     * @return EnableService
     */
    EnableService<Entity, ID> enableService();

    /**
     * 启用对象
     *
     * @param id id
     * @return 无返回
     */
    @PatchMapping("/enable/{id}")
    default Mono<Void> enableById(@PathVariable ID id) {
        return Mono.just(id)
                .filter(this::isValid)
                .flatMap(ReactorUtils.thenEmpty(enableService()::enableById));
    }

    /**
     * 禁用用对象
     *
     * @param id id
     * @return 无返回
     */
    @PatchMapping("/disable/{id}")
    default Mono<Void> disableById(@PathVariable ID id) {
        return Mono.just(id)
                .filter(this::isValid)
                .flatMap(ReactorUtils.thenEmpty(enableService()::enableById));
    }

    /**
     * 分页查询
     *
     * @param num    页码
     * @param size   条数
     * @param enable 启用状态
     * @return 分页数据
     */
    @GetMapping(value = "/page/{num}-{size}", params = "enable")
    default Mono<Page<VO>> findPageByEnable(@PathVariable Integer num,
                                            @PathVariable Integer size,
                                            @RequestParam("enable") SimpleStatus enable) {
        return Mono.just(PageRequest.of(num, size))
                .map(pageable -> enableService().findAll(enable.getEnable(), pageable))
                .map(page -> page.map(this::toVo));
    }
}
